package cn.com.guanying.android.logic;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import cn.com.guanying.javacore.v11.common.FLog;
import cn.com.guanying.javacore.v11.common.observer.Observer;
import cn.com.guanying.javacore.v11.common.observer.SimpleObservable;
import cn.com.guanying.javacore.v11.core.NetWorkModule;
import cn.com.guanying.javacore.v11.core.Request;
import cn.com.guanying.javacore.v11.interfaces.RequestListener;

public abstract class BaseLogic extends SimpleObservable implements  RequestListener{ 

	private boolean started = false;// 模块是否已经激活

	private final HandlerThread thread = new HandlerThread(this.getClass().getSimpleName() + "'s Data Thread");
	protected Handler handler;
	private Runnable mFrontOfQueueRunnable;
	private NetWorkModule netWorkModule = NetWorkModule.getInstance();
	public BaseLogic(){
		
	}
	/**
	 * @param useThread
	 *            是否需要线程，如果设置为true必须重写{@link#handleLogicThreadMessage}方法
	 */
	public BaseLogic(boolean useThread) {
		if (useThread) {
			thread.start();
			handler = new Handler(thread.getLooper()) {

				@Override
				public void handleMessage(Message msg) {
					try {
						handleLogicThreadMessage(msg);
					} catch (Exception e) {
						FLog.e(e.getMessage(), e);
					}
				}

			};
		}
		
	}

	public void sendRequest(Request request){
		netWorkModule.sendRequest(request);
	}
	
	/**
	 * 处理数据线程的消息队列，如果需要在逻辑层中使用数据线程时需要重写改方法
	 * 
	 * @param msg
	 *            相关的消息
	 */
	protected void handleLogicThreadMessage(Message msg) {
	}

	/**
	 * 发送消息到线程队列队首
	 * 
	 * @param what
	 *            消息类型
	 * @param obj
	 *            消息内容
	 * 
	 * @see#sendMessageAtFrontOfQueue(int what, int arg1, int arg2, Object obj)
	 */
	protected void sendMessageAtFrontOfQueue(int what, Object obj) {
		sendMessageAtFrontOfQueue(what, 0, 0, obj);
	}

	/**
	 * 发送消息到线程队列队首
	 * 
	 * @param what
	 *            消息类型
	 * @param arg1
	 *            消息额外参数1
	 * @param arg2
	 *            消息额外参数2
	 * @param obj
	 *            消息内容
	 */
	protected void sendMessageAtFrontOfQueue(int what, int arg1, int arg2, Object obj) {
		assert handler != null;
		Message msg = handler.obtainMessage(what, arg1, arg2, obj);
		handler.sendMessageAtFrontOfQueue(msg);
	}

	protected void sendMessageAtFrontOfQueueDelay(int what, Object obj, long delayMillis) {
		sendMessageAtFrontOfQueueDelay(what, 0, 0, obj, delayMillis);
	}

	protected void sendMessageAtFrontOfQueueDelay(final int what, final int arg1, final int arg2, final Object obj,
			long delayMillis) {
		assert handler != null;
		if (mFrontOfQueueRunnable != null) {
			handler.removeCallbacks(mFrontOfQueueRunnable);
		}
		mFrontOfQueueRunnable = new Runnable() {

			@Override
			public void run() {
				sendMessageAtFrontOfQueue(what, arg1, arg2, obj);
			}
		};
		handler.postDelayed(mFrontOfQueueRunnable, delayMillis);
	}

	protected void sendMessage(int what, Object obj) {
		sendMessage(what, 0, 0, obj);
	}

	protected void sendMessage(int what, int arg1, int arg2, Object obj) {
		assert handler != null;
		handler.sendMessage(handler.obtainMessage(what, arg1, arg2, obj));
	}

	/**
	 * @see#sendMessageDeley(int what, int arg1, int arg2, Object obj, long delayMillis)
	 */
	protected void sendMessageDeley(int what, Object obj, long delayMillis) {
		sendMessageDeley(what, 0, 0, obj, delayMillis);
	}

	/**
	 * <b>延迟发送消息</b>
	 * 
	 * <pre>
	 * 当在delayMillis时间间隔内收到了重复的消息时会将前一个消息移除队列，
	 * 并继续等待delayMillis毫秒后执行，一般在短时间内可能会多次触发相同任务时需使用此方法，
	 * 如联系人搜索，用户每输入一个字符都会触发一次搜索，调用此方法后只有当用户输入完后才
	 * 去搜索（这样就需要一个比较合适的delayMillis，目前搜索采用0.5秒得间隔来判定是否输入完成）
	 * </pre>
	 * 
	 * @param what
	 *            消息类型
	 * @param arg1
	 *            消息额外参数1，不需要时可以传递任意值
	 * @param arg2
	 *            消息额外参数2，不需要时可以传递任意值
	 * @param obj
	 *            消息内容，可以为null
	 * @param delayMillis
	 *            延迟时间
	 */
	protected void sendMessageDeley(int what, int arg1, int arg2, Object obj, long delayMillis) {
		assert handler != null;
		handler.removeMessages(what);
		Message msg = handler.obtainMessage(what, arg1, arg2, obj);
		handler.sendMessageDelayed(msg, delayMillis);
	}

	@Override
	public void addListener(Observer listener, int... eventIds) {
		super.addListener(listener, eventIds);
	}



	/**
	 * 此方法要求是可重入的, 即:可以重复调用此方法而没有消极影响
	 */
	public void start() {
		try {
			if (!started) {
				started = true;
				init();
			}
		} catch (Exception e) {
			FLog.e(e.getMessage(), e);
		}
	}

	/**
	 * 此方法要求是可重入的, 即:可以重复调用此方法而没有消极影响
	 */
	public void end() {
		if (started) {
			destroy();
			started = false;
		}
	}

	public boolean isStarted() {
		return started;
	}

	public boolean isEnd() {
		return !started;
	}

	protected abstract void init();

	protected abstract void destroy();

}
